/**
 * @(#)Client.java
 *
 *
 * @author
 * @version 1.00 2012/4/1
 */

import java.net.ServerSocket;
import java.net.Socket;
import java.io.*;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Client {

	private Socket ctos;
	private Scanner fromServer;
	private PrintWriter toServer;
	private ConnectFourCore game;

    public Client(String host, int port) {
    	ctos = null;
    	fromServer = null;
    	toServer = null;
    	connect(host, port);
    }

	public void setGame(ConnectFourCore game) { this.game = game; }
    public ConnectFourCore getGame() { return game; }

    public void connect(String host, int port)
    {
    	if(ctos.isBound()) {
    		System.err.println("The client is already bound to a server.");
    		return;
    	}
    	try {
    		ctos = new Socket(host, port);
    		fromServer = new Scanner(ctos.getInputStream());
    		toServer = new PrintWriter(ctos.getOutputStream());
    	}
    	catch (UnknownHostException e) {
    		System.err.println("Unkown host: " + host);
    		System.exit(1);
    	}
    	catch (IOException e) {
    		System.err.println("I/O connection failed for: " + host);
    		System.exit(1);
    	}
    }

    public void disconnect() throws IOException
    {
    	if(ctos == null) {
    		System.err.println("No connection to close.");
    		return;
    	}
    	if(!ctos.isClosed()) {
    		if(toServer != null) toServer.close();
	    	if(fromServer != null) fromServer.close();
	    	try { ctos.close(); }
	    	catch (IOException e) {
	    		System.err.println("Couldn't close the connection to the server.");
    			System.exit(1);
	    	}
    	}
    	toServer = null;
    	fromServer = null;
    	ctos = null;
    }

    public Boolean ackServerGameInfo()
    {
    	if(toServer == null) return false;
    	if(!ctos.isConnected()) return false;

    	toServer.println("READY");
    	return true;
    }
    public Boolean ackServerMove()
    {
    	if(fromServer == null) return false;
    	if(!ctos.isConnected()) return false;

    	if(fromServer.hasNextLine())
    	{
    		String[] data = fromServer.nextLine().split(" ");
    		if(data.length != 0 && data.length < 3) {
    			processMove((data[0].toLowerCase().toCharArray()[0]),Integer.parseInt(data[1].toLowerCase()));
    		} else { return false; }
    	}

    	toServer.println("OK");
    	return true;
    }
    public Boolean sendServerMove(char move, int col)
    {
    	if(toServer == null) return false;
    	if(!ctos.isConnected()) return false;

    	toServer.println(move + ((col == 0) ? "" : (" " + col)));

    	if(fromServer.hasNextLine()&&fromServer.nextLine().trim().toUpperCase().equals("OK"))
    	{
    		processMove(move, col);
    		return true;
    	}

    	return false;
    }

    private Boolean processMove(char move, int col)
	{
		switch(move)
		{
			case 'd':
				game.Drop(col);
				return true;
			case 'r':
				game.Remove(col);
				return true;
			case 'f':
				game.Flip();
				return true;
		}
		return false;
	}



}